package vip.liux.front.infrastructure.aop.interceptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import vip.liux.core.utils.JsonUtils;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.time.Clock;
import java.util.HashMap;
import java.util.Map;


public class AuditingHelper implements IAuditingHelper {
    private final Logger logger = LoggerFactory.getLogger(AuditingHelper.class);

    @Override
    public AuditLogInfo createAuditLogInfo() {
        AuditLogInfo logInfo = new AuditLogInfo();
        logInfo.setApplicationName("front");
        return logInfo;
    }

    @Override
    public AuditLogActionInfo createAuditLogAction(AuditLogInfo auditLog, Class<?> type, Method method, Object[] arguments) {
        return createAuditLogAction(auditLog, type, method, createArgumentsMap(method, arguments));
    }

    @Override
    public AuditLogActionInfo createAuditLogAction(AuditLogInfo auditLog, Class<?> type, Method method, Map<String, Object> arguments) {
        AuditLogActionInfo actionInfo = new AuditLogActionInfo();
        actionInfo.setServiceName(type.getName());
        actionInfo.setMethodName(method.getName());
        actionInfo.setParameters(SerializeConvertArguments(arguments));
        actionInfo.setExecutionDuration(((int) Clock.systemUTC().millis()));
        return actionInfo;
    }

    protected String SerializeConvertArguments(Map<String, Object> arguments) {
        try {
            if (arguments == null || arguments.isEmpty()) {
                return "{}";
            }

            Map<String, Object> map = new HashMap<>();

            for (Map.Entry<String, Object> entry : arguments.entrySet()) {
                if (entry.getValue() != null && entry.getValue().getClass().isEnum()) {
                    map.put(entry.getKey(), null);
                } else {
                    map.put(entry.getKey(), entry.getValue());
                }
            }

            return JsonUtils.toJson(map);
        } catch (Exception e) {
            logger.warn("序列化参数失败", e);
            return "{}";
        }
    }

    protected Map<String, Object> createArgumentsMap(Method method, Object... arguments) {
        Parameter[] parameters = method.getParameters();

        Map<String, Object> map = new HashMap<>();

        for (int i = 0; i < parameters.length; i++) {
            map.put(parameters[i].getName(), arguments[i]);
        }
        return map;
    }
}
